/**
 * 2017年4月25日
 */
package util.tags;

import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.Iterator;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

import util.annotation.JspTableColumnIgnore;
import util.annotation.JspTableColumnName;
import util.annotation.JspTableEntity;

/**
 * @author Alex
 *
 */
public class TableIteratorTag extends BaseTag{
	private String dataSource = null;
	private String tableClass = "table";
	private String tableTrClass = "info";
	private String tableTdClass = "info";

	private String extendColName = null;
	
	
	protected String bodyContent = null;
	Field [] fields;
	JspWriter out;
	public void doTag() throws JspException,IOException{
		out = getJspContext().getOut();
		StringWriter sw = new StringWriter(100);
		getJspBody().invoke(sw);
		this.bodyContent = sw.toString().replaceAll("\r|\n", "");
		
		Iterable<?> it = (Iterable<?>) this.getJspContext().getAttribute(dataSource);
		if(it == null){
			it = (Iterable<?>)pageContext.getRequest().getAttribute(dataSource);
		}
		if(it == null){
			out.println("elements is null ,please check");
			return ;
		}
		
		//TODO:当iterator里面没有元素的时候,会报异常,这里需要处理这个异常.
		Iterator<?> iter = it.iterator();
		Object first = iter.next();
		Class<?> clz = first.getClass();
		StringBuilder sb = new StringBuilder();
		if(clz.isAnnotationPresent(JspTableEntity.class)){
			fields = clz.getDeclaredFields();
			for(Field f:fields){
				if(f.isAnnotationPresent(JspTableColumnIgnore.class)){
					continue;
				}
				f.setAccessible(true);
				if(f.isAnnotationPresent(JspTableColumnName.class)){
					JspTableColumnName jtcn = f.getAnnotation(JspTableColumnName.class);
					String colName = jtcn.colName();
					sb.append(colName).append(" ");
				}else{
					sb.append(f.getName()).append(" ");
				}
			}
			
		}
		String colArr[] = sb.toString().split(" ");
		beginTable();
		beginThead();
		beginTr();
		for(String s:colArr){
			out.println("<th class=\""+tableTdClass+"\">"+s+"</th>");
		}
		outEx();
		endTr();
		endThead();
		beginTbody();
		out.println(toTr(first));
		while(iter.hasNext()){
			out.println(toTr(iter.next()));
		}
		endTbody();
		endTable();
	}
	protected void outEx() throws IOException{
		if(this.bodyContent!=null && this.bodyContent.length()>0){
			out.println("<th class=\""+tableTdClass+"\">"+this.extendColName+"</th>");
		}
	}
	
	protected void beginThead() throws IOException{
		out.println("<thead class=\""+tableTrClass+"\">");
	}
	/**
	 * @param extendColName the extendColName to set
	 */
	public void setExtendColName(String extendColName) {
		this.extendColName = extendColName;
	}
	/**
	 * @param bodyContent the bodyContent to set
	 */
	public void setBodyContent(String bodyContent) {
		this.bodyContent = bodyContent;
	}
	/**
	 * @param fields the fields to set
	 */
	public void setFields(Field[] fields) {
		this.fields = fields;
	}
	/**
	 * @param out the out to set
	 */
	public void setOut(JspWriter out) {
		this.out = out;
	}
	protected void endThead() throws IOException{
		out.println("</thead>");
	}
	protected void beginTr() throws IOException{
		out.println("<tr class=\""+tableTrClass+"\">");
	}
	protected void endTr() throws IOException{
		out.println("</tr>");
	}

	protected void beginTbody() throws IOException{
		out.println("<tbody>");
	}
	protected void endTbody() throws IOException{
		out.println("</tbody>");
	}
	protected void beginTable() throws IOException{
		out.println("<table class=\""+tableClass+"\">");
	}
	protected void endTable()  throws IOException{
		out.println("</table>");
	}
	public void setTableClass(String tableClass) {
		this.tableClass = tableClass;
	}
	public void setTableTrClass(String tableTrClass) {
		this.tableTrClass = tableTrClass;
	}
	public void setTableTdClass(String tableTdClass) {
		this.tableTdClass = tableTdClass;
	}
	public void setDataSource(String dataSource) {
		this.dataSource = dataSource;
	}
	private String toTr(Object o){
		String str = "<tr class=\""+tableTrClass+"\">";
		for(Field f:this.fields){
			if(f.isAnnotationPresent(JspTableColumnIgnore.class)) continue;
			try {
				str += "<td class=\""+tableTdClass+"\">"+f.get(o).toString()+"</td>";
			} catch (Exception e) {
				// TODO Auto-generated catch block
				str += "<td class=\""+tableTdClass+"\">"+e.getMessage()+"</td>";
			}	
		}
		if(this.extendColName!=null && this.extendColName.length()>0){
			str += "<td class=\""+tableTdClass+"\">"+this.bodyContent+"</td>";
		}
		str+="</tr>";
		return str;
	}
	

}
